﻿#pragma once

#include "acis/dcl_cstr.h"
#include "acis/acis.hxx"
#include "acis/api.hxx"

#include "acis/curdef.hxx"
#include "acis/vector.hxx"
#include "acis/unitvec.hxx"
#include "acis/position.hxx"

/*
* 设计一种二次曲线参数化方法，完成xy_ell_param_range，xy_ell_evaluate，xy_ell_param等几个接口的实现，可以只考虑椭圆圆的情况，双曲线抛物线暂不做要求
*/
class xy_ell {
public:
	// 构造函数
	xy_ell(
		SPAposition const& center,
		SPAunit_vector const& normal,
		SPAvector const& maj_axis,
		double                ratio
	) : centre(center), normal(normal), major_axis(maj_axis), radius_ratio(ratio) {}

	// 拷贝构造函数
	xy_ell(xy_ell const& name) : centre(name.centre), normal(name.normal), major_axis(name.major_axis), radius_ratio(name.radius_ratio) {};

	// 析构
	~xy_ell() {}

	// 曲线中心点
	SPAposition centre;

	// 曲线主轴
	SPAvector major_axis;

	// 曲线法线
	SPAunit_vector normal;

	// 曲线长短轴比例 min_axis = major_axis * radius_ratio 
	double radius_ratio;

	/************************************以下为需要实现的接口************************************/

	/**
	 * @brief    计算自定义参数化的曲线参数范围
	 * @return   函数执行结果
	 */
	DECL_KERN SPAinterval xy_ell_param_range() const;

	/**
	 * @brief              根据给定的参数值，求解曲线在该参数值处的点坐标，以及一阶二阶导数向量
	 * @details            根据自定义的参数化方法，找到给定参数值处的唯一点坐标，以及该点处的一阶二阶导数向量
	 * @param[in]          val     给定的参数值
	 * @param[out]         pos     接收计算的点坐标
	 * @param[out]         first   接收计算的一阶导数向量
	 * @param[out]         second  接收计算的二阶导数向量
	 * @return             函数执行结果
	 */
	DECL_KERN void xy_ell_evaluate(
		double val,
		SPAposition& pos,
		SPAvector& first = SpaAcis::NullObj::get_vector(),
		SPAvector& second = SpaAcis::NullObj::get_vector()
	) const;

	/**
	* @brief        根据给定的点坐标，求解曲线在该点的参数值   
	* @details      根据自定义的参数化方法，找到给定点对应的唯一的参数值（需要考虑点不在曲线的情况,如果不在，将曲线等比例扩大或缩小到使点能经过曲线，空间点首先需要将点投影到曲线的所在的平面内）
	* @param[in] 	pos 给定的坐标点
	* @return		函数执行结果
	*/
	DECL_KERN double xy_ell_param(SPAposition const& pos) const;

	/**
	 * @brief      根据给定的点坐标，求解曲线在该点的曲率
	 * @details    根据自定义的参数化方法，计算给定点处的曲线曲率
	 * @param[in]  pos  给定的点坐标
	 * @return     函数执行结果
	 */
	DECL_KERN SPAvector xy_ell_point_curvature(
		SPAposition const& pos
	);

	/**
	 * @brief      根据给定的点坐标，求解曲线在该点的切向（一阶导数）
	 * @details    根据自定义的参数化方法，计算给定点处的切向
	 * @param[in]  pos  给定的点坐标
	 * @return     函数执行结果
	 */
	DECL_KERN SPAunit_vector xy_ell_point_direction(
		SPAposition const& pos
	) const;

	// 如需要其余辅助函数等可自行定义
};

